import catchError from './catchError'
import mapping from '../mapping'
//请求时间阈值
const MIN_LEN = 360;
const MAX_LEN = 10000;
//是否显示遮罩
const SHOW_LOADING = true;
//响应成功状态码
const SUCCESS_CODE = [true, 200];
//状态码字段
const FILED_CODE = 'code';
//消息字段
const FILED_MESSAGE = 'msg';
//需要跳转登陆页面的code码
const TO_LOGIN_CODE = [101];
// ----------------------------------------------------
let ui = mapping.J_ui();
let ROUTE_LOGIN_PAGE = null;
//初始化时间差
let cuo = 0;
//最大时长计时器
let timer = undefined;
//接口队列集合
let iQuee = new Map();
// 遮罩文本内容
let loadingText = 'loading...';
//请求中loading的配置参数
let httpLoadingOptions = {
  spinner: 'el-icon-loading',
  background: 'rgba(0, 0, 0, 0.4)',
  customClass: 'http-loading',
  text: loadingText,
  body: true
};
//遮罩对象
let loadingInstance = undefined;
// ----------------------------------------------------
function showErrorMessage(msg = false) {
  if (!msg) return
  if (ui === 'element') {
    this.$message.error(msg)
  } else if (ui === 'iview') {
    this.$Message.error(msg)
  } else if (ui === 'vant') {
    this.$toast.fail(msg)
  }
}

function closeLoading() {
  if (ui === 'element') {
    loadingInstance.close()
  } else if (ui === 'iview') {
    loadingInstance.hide()
  } else if (ui === 'vant') {
    loadingInstance.clear()
  }
}

function showLoading() {
  if (ui === 'element') {
    return this.$loading(httpLoadingOptions)
  } else if (ui === 'iview') {
    this.$Spin.show()
	return this.$Spin
  } else if (ui === 'vant') {
    return this.$toast.loading(loadingText)
  }
}
// ----------------------------------------------------
const clearLoading = resPromise => {
  if (iQuee.has(resPromise)) iQuee.delete(resPromise)
  if (iQuee.size === 0) {
    let ca = new Date().getTime() - cuo; //累计请求用时
    let wait = 0;
    if (MIN_LEN > ca) wait = MIN_LEN - ca;
    loadingInstance && setTimeout(() => closeLoading(), wait)
    //重置为初始状态 重置计时器
    cuo = 0;
    clearTimeout(timer);
    timer = undefined;
  }
}

export default tools => {
  ROUTE_LOGIN_PAGE = mapping.J_sys.ROUTE_LOGIN_PAGE
  return function(promise, successBack, errorBack) {
    //如果为初始化状态则设定开始时间,并且不隐藏loading
    if (cuo === 0 && SHOW_LOADING) {
      cuo = new Date().getTime()
      //loading加载,默认有loading
      loadingInstance = showLoading.call(this)
      timer = setTimeout(() => {
        closeLoading()
        catchError({
          response: {
            status: 408
          }
        })
      }, MAX_LEN)
    }

    const resPromise = new Promise((resolve, reject) => {
      promise.then(res => {
        if (tools.identify(res, 'object')) {
          if (SUCCESS_CODE.includes(res[FILED_CODE])) {
            successBack && successBack(res);
            resolve(res);
          } else if (TO_LOGIN_CODE.includes(res[FILED_CODE])) {
            if (errorBack) {
              errorBack(res);
            } else {
              //非登陆页面调跳转到登陆页面
              if (this.$route.name === ROUTE_LOGIN_PAGE) {
                //不成功默认提示线上内容
                showErrorMessage.call(this, res[FILED_MESSAGE])
              } else {
                if (this.$route.meta.noCheck) {
                  //不需要权限校验的页面单独剥离出来
                } else {
                  this.$router.replace({
                    name: ROUTE_LOGIN_PAGE
                  })
                }
              }
            }
            reject(res);
          } else {
            errorBack && errorBack(res)
            //不成功默认提示线上内容
            showErrorMessage.call(this, res[FILED_MESSAGE])
            reject(res);
          }
        } else {
          successBack && successBack(res);
          resolve(res);
        }
      }).catch(error => {
        catchError(error);
        reject(error)
      }).finally(() => SHOW_LOADING && clearLoading(resPromise))
    })
    iQuee.set(resPromise, resPromise);
    return resPromise;
  }
}
